import random
from hashlib import md5
from redis import ConnectionPool, StrictRedis


class SimpleHash(object):
    def __init__(self, cap, seed):
        self.cap = cap
        self.seed = seed

    def hash(self, value):
        ret = 0
        for i in range(len(value)):
            ret += self.seed * ret + ord(value[i])
        return (self.cap - 1) & ret


class RedisClient(object):
    pool = ConnectionPool(**{
        'host': '129.211.169.177',
        'port': 6379,
        'db': 5,
        'password': 950218
    })
    client = StrictRedis(connection_pool=pool)

    def reConnect(self):
        try:
            self.client.ping()
        except:
            self.client =StrictRedis(connection_pool=self.pool)


    def __init__(self, blockNum=1, key='periodicalfilter'):
        self.bit_size = 1 << 31
        self.seeds = [5, 7, 11, 13, 31, 37, 61]
        self.key = key
        self.blockNum = blockNum
        self.hashfunc = []
        for seed in self.seeds:
            self.hashfunc.append(SimpleHash(self.bit_size, seed))

    def isContains(self, str_input):
        self.reConnect()
        if not str_input:
            return False
        m5 = md5()
        m5.update(str_input.encode('utf-8'))
        str_input = m5.hexdigest()
        ret = True
        name = self.key + str(int(str_input[0:2], 16) % self.blockNum)
        for f in self.hashfunc:
            loc = f.hash(str_input)
            ret = ret & self.client.getbit(name, loc)
        return ret

    def insert(self, str_input):
        m5 = md5()
        m5.update(str_input.encode('utf-8'))
        str_input = m5.hexdigest()
        name = self.key + str(int(str_input[0:2], 16) % self.blockNum)
        for f in self.hashfunc:
            loc = f.hash(str_input)
            self.client.setbit(name, loc, 1)

    def set_cookies(self, cookies):
        self.reConnect()
        self.client.set('cookies', cookies)

    def get_cookies(self):
        self.reConnect()
        return str(self.client.get('cookies'), encoding='utf-8')

    def set_ixueshu_cookies(self, cookies):
        self.reConnect()
        self.client.set('ixueshu_cookies', cookies)

    def get_ixueshu_cookies(self):
        self.reConnect()
        return str(self.client.get('ixueshu_cookies'), encoding='utf-8')

    def ADSL(self):
        self.reConnect()
        key = 'adsl'
        try:
            keys = self.client.hkeys(key)
            if keys is None:
                return None
            else:
                selectkey = random.choice(keys)
                ip = self.client.hget(key, selectkey)
                return selectkey, str(ip.decode())
        except:
            return None

    def set_scroll(self, id):
        self.reConnect()
        self.client.set('scroll_id', id)

    def get_scroll(self):
        self.reConnect()
        scroll = self.client.get("scroll_id")
        if scroll:
            return str(scroll, encoding='utf-8')
        else:
            return 0

    def set_p_scroll(self, id):
        self.reConnect()
        self.client.set('p_scroll_id', id)

    def get_p_scroll(self):
        self.reConnect()
        scroll = self.client.get("p_scroll_id")
        if scroll:
            return str(scroll, encoding='utf-8')
        else:
            return 0

    def set_periodical_scroll(self, id):
        self.reConnect()
        self.client.set('periodical_scroll_id', id)

    def get_periodical_scroll(self):
        self.reConnect()
        scroll = self.client.get("periodical_scroll_id")
        if scroll:
            return str(scroll, encoding='utf-8')
        else:
            return 0

    def get_one_periodical(self):
        self.reConnect()
        article = self.client.rpop('periodical')
        if article:
            return str(article,encoding='utf-8')

    def checkStop(self):
        self.reConnect()
        signal = self.client.get('stop')
        return str(signal, encoding='utf-8')

    def setADSL(self, data):
        self.reConnect()
        self.client.hset('adsl_tianqi', str(data['expire']), f'{data["ip"]}:{data["port"]}')

    def getADSL(self):
        self.reConnect()
        key = 'adsl_tianqi'
        try:
            keys = self.client.hkeys(key)
            if keys is None:
                return None
            else:
                selectkey = random.choice(keys)
                ip = self.client.hget(key, selectkey)
                return selectkey, str(ip.decode())
        except:
            return None



if __name__ == '__main__':
    r = RedisClient()
